#include <vtkForceDirectedLayoutStrategy.h>
#include <vtkGraphLayoutView.h>
#include <vtkMutableUndirectedGraph.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>

#include <vtkArcSource.h>
#include <vtkPolyDataMapper.h>
#include "vtkPolygon.h"
#include "vtkProperty.h"

#include "vtkLookupTable.h"
#include "vtkMinimalStandardRandomSequence.h"
#include "vtkCellData.h"
#include "vtkFloatArray.h"

#include "vtkGlyph3DMapper.h"
#include "vtkSphereSource.h"

#include "vtkInteractorStyleTrackballCamera.h"
#include "vtkPolyDataMapper2D.h"
#include "vtkMapper2D.h"
#include "vtkActor2D.h"
#include "vtkCamera.h"
#include "vtkProperty2D.h"
#include "vtkProp3D.h"
#include "vtkInteractorStyleTrackballCamera.h"
#include "vtkPropPicker.h"
#include "vtkPlaneSource.h"


namespace {
// Handle mouse events
    class MouseInteractorHighLightActor : public vtkInteractorStyleTrackballCamera
    {
    public:
        static MouseInteractorHighLightActor* New();
    vtkTypeMacro(MouseInteractorHighLightActor,
                 vtkInteractorStyleTrackballCamera);

        MouseInteractorHighLightActor()
        {
            LastPickedActor = NULL;
            LastPickedProperty = vtkProperty::New();
        }
        virtual ~MouseInteractorHighLightActor()
        {
            LastPickedProperty->Delete();
        }
        virtual void OnLeftButtonDown() override
        {
            vtkNew<vtkNamedColors> colors;

            int* clickPos = this->GetInteractor()->GetEventPosition();

            // Pick from this location.
            vtkNew<vtkPropPicker> picker;
            picker->Pick(clickPos[0], clickPos[1], 0, this->GetDefaultRenderer());


            vtkSmartPointer<vtkActorCollection> actorCollection = this->GetDefaultRenderer()->GetActors();
            for (int i = 0; i < actorCollection->GetNumberOfItems(); ++i) {
                vtkSmartPointer<vtkObject> obj = this->GetDefaultRenderer()->GetActors()->GetItemAsObject(i);
                if (obj->IsA("vtkObject")) {
                    vtkSmartPointer<vtkActor> actor = vtkActor::SafeDownCast(obj);
                    std::cout << "actor: " << actor->GetProperty()->GetColor()[0];
                }


            }

//            // If we picked something before, reset its property
//            if (this->LastPickedActor)
//            {
//                this->LastPickedActor->GetProperty()->DeepCopy(this->LastPickedProperty);
//            }
//            this->LastPickedActor = picker->GetActor();
////            if (this->LastPickedActor)
////            {
////                // Save the property of the picked actor so that we can
////                // restore it next time
////                this->LastPickedProperty->DeepCopy(this->LastPickedActor->GetProperty());
////                // Highlight the picked actor by changing its properties
////                this->LastPickedActor->GetProperty()->SetColor(
////                        colors->GetColor3d("Red").GetData());
////                this->LastPickedActor->GetProperty()->SetDiffuse(1.0);
////                this->LastPickedActor->GetProperty()->SetSpecular(0.0);
////                this->LastPickedActor->GetProperty()->EdgeVisibilityOn();
////            }
//
//            if (this->LastPickedActor->GetProperty()->GetColor()[0] == 255) {
//                this->LastPickedActor->GetProperty()->SetColor(255, 0, 0);
//                vtkNew<vtkUnsignedCharArray> cellData;
//                cellData->SetNumberOfComponents(4);
//                vtkSmartPointer<vtkPolyDataMapper> planeSourceMapper = vtkPolyDataMapper::SafeDownCast(this->LastPickedActor->GetMapper());
//                auto cellCount = planeSourceMapper->GetInput()->GetNumberOfCells();
//                cellData->SetNumberOfTuples(cellCount);
//                for (int i = 0; i < cellCount; ++i) {
//                    double color[4] = {100, 100, 100, 255};
//                    cellData->InsertTuple(i, color);
//                }
//                planeSourceMapper->GetInput()->GetCellData()->SetScalars(cellData);
//            }

            // Forward events
            vtkInteractorStyleTrackballCamera::OnLeftButtonDown();
        }

    private:
        vtkActor* LastPickedActor;
        vtkProperty* LastPickedProperty;
    };

    vtkStandardNewMacro(MouseInteractorHighLightActor);
}


int main(int, char*[]) {
    vtkNew<vtkRenderer> renderer;
    vtkNew<vtkRenderWindow> renderWindow;
    renderWindow->SetWindowName("RegularPolygonSource");
    renderWindow->AddRenderer(renderer);
    vtkNew<vtkRenderWindowInteractor> renderWindowInteractor;
//    renderWindowInteractor->SetInteractorStyle(vtkNew<vtkInteractorStyleTrackballCamera>)
    renderWindowInteractor->SetRenderWindow(renderWindow);


    vtkNew<vtkNamedColors> colors;


    const int RowCount = 36;
    const int ColCount = 40;
    const double RowDegree = vtkMath::Pi() * 2 / RowCount;
    const double Radius = 500;
    const int AreaAvgRadius = Radius / ColCount;
    const int ArcSegmentCount = 1;
    double ArcSegmentDegree = RowDegree / ArcSegmentCount;

    vtkNew<vtkCellArray> allPolygons;
    vtkNew<vtkPoints> allPoints;
    vtkNew<vtkPolyData> polygonPolyData;

    for (int i = 0; i < RowCount; ++i) {

        double degree = RowDegree * i;

        for (int j = 0; j < ColCount; ++j) {

            vtkNew<vtkPolygon> polygon;
            polygon->GetPointIds()->SetNumberOfIds((ArcSegmentCount + 1) * 2);
            vtkIdType numberOfPoints = allPoints->GetNumberOfPoints();

            double radius0 = j * AreaAvgRadius;
            double radius1 = (j + 1) * AreaAvgRadius;

            for (int k = 0; k < ArcSegmentCount + 1; ++k) {
                double d0 = degree + (ArcSegmentDegree) * k;
                double x0 = cos(d0) * radius0;
                double y0 = sin(d0) * radius0;
                allPoints->InsertNextPoint(x0, y0, 0.0);

                double d1 = degree + (ArcSegmentDegree) * k;
                double x1 = cos(d1) * radius1;
                double y1 = sin(d1) * radius1;
                allPoints->InsertNextPoint(x1, y1, 0.0);

                polygon->GetPointIds()->SetId(k, numberOfPoints + (ArcSegmentCount - k));
                polygon->GetPointIds()->SetId(k + ArcSegmentCount + 1, numberOfPoints + ArcSegmentCount + 1 + k);
            }

            allPolygons->InsertNextCell(polygon);
        }
    }

    polygonPolyData->SetPoints(allPoints);
    polygonPolyData->SetPolys(allPolygons);


    vtkNew<vtkPolyDataMapper> mapper;
    mapper->SetInputData(polygonPolyData);

    vtkNew<vtkActor> actor;
    actor->SetMapper(mapper);
    actor->GetProperty()->EdgeVisibilityOn();
    actor->GetProperty();
    renderer->AddActor(actor);

    vtkNew<vtkCamera> camera;
    camera->SetPosition(0, 0, 1400);
    camera->SetFocalPoint(0, 0, 0);
    camera->SetViewUp(0, 1, 0);
    renderer->SetActiveCamera(camera);
    renderer->ResetCameraClippingRange();


    // Set the custom type to use for interaction.
    vtkNew<MouseInteractorHighLightActor> style;
    style->SetDefaultRenderer(renderer);
    renderWindowInteractor->SetInteractorStyle(style);


    {
        vtkNew<vtkPlaneSource> planeSource;
        planeSource->SetCenter(0, 0, -1);
        planeSource->SetOrigin(-500, 500, -1);
        planeSource->SetPoint1(500, 500, -1);
        planeSource->SetPoint2(-500, -500, -1);
    //    planeSource->SetResolution(10, 10);
        planeSource->SetXResolution(10);
        planeSource->SetYResolution(10);
        planeSource->Update();

        vtkNew<vtkPolyDataMapper> planeSourceMapper;
        planeSourceMapper->SetInputConnection(planeSource->GetOutputPort());
        planeSourceMapper->Update();

//        vtkSmartPointer<vtkCellData> cellData = planeSourceMapper->GetInput()->GetCellData();

        // 设置颜色
        vtkNew<vtkUnsignedCharArray> cellData;
        cellData->SetNumberOfComponents(4);
        auto cellCount = planeSourceMapper->GetInput()->GetNumberOfCells();
        cellData->SetNumberOfTuples(cellCount);
        for (int i = 0; i < cellCount; ++i) {
            double color[4] = {200, 200, 200, 40};
            cellData->InsertTuple(i, color);
        }
        planeSourceMapper->GetInput()->GetCellData()->SetScalars(cellData);


        vtkNew<vtkActor> plane;
        plane->SetMapper(planeSourceMapper);
        plane->GetProperty()->SetColor(100, 0, 0);
//        plane->ForceTranslucentOn();
        renderer->AddActor(plane);
    }


    renderWindow->Render();
//    renderWindowInteractor->Disable();
    renderWindowInteractor->Initialize();
    renderWindowInteractor->Start();







    return EXIT_SUCCESS;
}